package me.dqn.enhance;

import me.dqn.annotation.DAspect;
import me.dqn.aspect.ProxyAspect;
import me.dqn.callback.AfterCallback;
import me.dqn.callback.AroundCallback;
import me.dqn.callback.BeforeCallBack;
import me.dqn.filter.EnhanceFilter;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;

import java.lang.reflect.InvocationTargetException;

/**
 * @author dqn
 * 2018/5/12--1:16
 * 用来增强目标类型。
 * 对before、after、around 三种通知注册callback。
 * 使用 EnhanceFilter 来区分什么时候使用那个callback
 */
public class DEnhancer<T> {
    public T enhance(Class<T> tClass) {
        T target = null;
        if (tClass.isAnnotationPresent(DAspect.class)) {
            DAspect dAspect = tClass.getAnnotation(DAspect.class);
            Class<? extends ProxyAspect> myAspect = dAspect.value();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(tClass);
            enhancer.setCallbackFilter(new EnhanceFilter());

            Callback before = new BeforeCallBack(myAspect);
            Callback after = new AfterCallback(myAspect);
            Callback around = new AroundCallback(myAspect);
            Callback[] callbacks = new Callback[]{before, after, around};

            enhancer.setCallbacks(callbacks);
            target = (T) enhancer.create();
        }
        return target;
    }
}
